﻿using System;
using System.Collections.Generic;
using DeSleeper.Client.Framework;
using DeSleeper.Client.Installation;
using DeSleeper.Library;
using DeSleeper.Library.Tasks;

namespace DeSleeper.Client.Service
{
    public class UninstallServiceCommand : ServiceCommand
	{
		public override string Text
		{
			get { return "uninstall"; }
		}

		protected override void OnExecute(object parameter)
		{
            var serviceParameters = parameter as InstallServiceParameters;
            if (serviceParameters.InstallTargets.IncludesLocal)
            {
                var installer = new Installer();
                installer.StopService();
                installer.UninstallService();
            }

		    uninstallRemote(serviceParameters);
		}

        private void uninstallRemote(InstallServiceParameters serviceParameters)
        {
            var exceptions = new List<Exception>();
            var targets = serviceParameters.InstallTargets;
            foreach (var machineName in targets.CompatibleAndUnknownRemote)
            {
                try
                {
                    if (!Installer.IsInstalled(machineName)) continue;

                    var installer = new Installer();
                    var uninstallStartInfo = installer.GetUninstallInfo();
                    uninstallStartInfo.CreateNoWindow = true;
                    var uninstallProcess = RemoteProcess.Start(uninstallStartInfo, machineName);
                    uninstallProcess.WaitForExit();
                }
                catch (Exception e)
                {
                    addException(exceptions, machineName, e);
                }
            }

            if (exceptions.Count == 1)
                throw new SelfFlatteningException(string.Empty, exceptions[0]);
            else if (exceptions.Count > 1)
                throw new SelfFlatteningAggregateException(exceptions);
        }

		/// <exception cref="ArgumentException">
		/// <see cref="InstallServiceCommand"/> requires a <see cref="InstallServiceParameters"/> parameter.
		/// </exception>
		public override bool CanExecute(object parameter)
		{
			var serviceParameters = parameter as InstallServiceParameters;
            return serviceParameters != null ? serviceParameters.IsInstalled : base.CanExecute(parameter);
		}

        private void addException(ICollection<Exception> exceptions, string machineName, Exception exception)
        {
            exceptions.Add(new SelfFlatteningException(
                               string.Format(
                                   @"An error occurred while attempting to uninstall the deSleeper service on {0}.",
                                   machineName)
                               , exception));
        }
	}
}
